package com.helios.core.service;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;

import com.helios.core.bean.Bean;
import com.helios.core.function.DeleteFunction;
import com.helios.core.function.SelectFunction;
import com.helios.core.function.UpdateFunction;
import com.helios.core.util.RedisUtil;

/**
 * Service的公共内容
 * 
 */
public abstract class ServiceAdapter<T extends Bean> {
    
    private final Logger logger = LogManager.getLogger(getClass());
    
    @Value("#{configProperties.bean_cache_time}")
    private int cacheTime;
    
    /**
     * 获取模块信息.
     */
    protected abstract String getDispInfo();
    
    /**
     * 通过args获取缓存的key.
     */
    protected abstract String getCacheKey(Object args);
    
    /**
     * 获取Bean.
     * 
     * 先去获取缓存中的对象,如果缓存中不存在,会调用function的get方法,传递的参数就是key.
     * 
     * @param key 获取bean的关键词
     * @param clazz 获取bean的类型
     * @param function 获取数据库的动作
     */
    protected final T getCache(Object key, Class<T> clazz, SelectFunction<T> function) {
        T bean = RedisUtil.getBean(getCacheKey(key), clazz);
        if(bean == null) {
            try {
                bean = function == null ? null : function.get(key);
            } catch (Exception e) {
                logger.error("获取[" + getDispInfo() + "]异常,原因:" + e.getMessage());
            }
            if(bean != null && getCacheTime() > 0) {
                RedisUtil.putBean(getCacheKey(key), bean, getCacheTime());
            }
        }
        return bean;
    }
    
    /**
     * 更新Bean.
     * 
     * @param bean 要更新的bean,不能为null
     * @param function 数据库更新动作,如果为null,只更新缓存
     * 
     * @return 是否更新成功
     */
    protected final boolean updateCache(T bean, UpdateFunction<T> function) {
        if(bean == null) return false;
        try {
            if(function != null) function.update(bean);
        } catch (Exception e) {
            logger.error("更新[" + getDispInfo() + "]异常,原因:" + e.getMessage());
            return false;
        }
        if(getCacheTime() > 0) RedisUtil.putBean(getCacheKey(bean), bean, getCacheTime());
        return true;
    }

    /**
     * 删除Bean.
     * 
     * @param id 要删除bean的id,必须为非负数
     * @param function 数据库删除动作,如果为null,只删除缓存
     * 
     * @return 是否删除成功
     */
    protected final boolean deleteCache(Integer id, DeleteFunction function) {
        if(id < 0) return false;
        try {
            if(function != null) function.delete(id);
        } catch (Exception e) {
            logger.error("删除[" + getDispInfo() + "]异常,原因:" + e.getMessage());
            return false;
        }
        if(getCacheTime() > 0) {
            RedisUtil.delBean(getCacheKey(id));
        }
        return true;
    }
    
    /**
     * 设置缓存时间.
     */
    protected int getCacheTime() {
        return cacheTime;
    }
}
